package com.ttx.http.demo.config;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.StreamUtils;

import java.io.*;
import java.nio.charset.Charset;

/**
 * 来源: http://www.imooc.com/wenda/detail/582968
 *
 * 用于resttemplate打印日志
 *
 * @author TimFruit
 * @date 19-12-31 上午1:46
 */
public class LoggingRequestInterceptor implements ClientHttpRequestInterceptor {
    final static Logger log = LoggerFactory.getLogger(LoggingRequestInterceptor.class);

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        traceRequest(request, body);
        ClientHttpResponse response = execution.execute(request, body);

        response=traceResponse(response);
        return response;
    }

    private void traceRequest(HttpRequest request, byte[] body) throws IOException {
        log.info("===========================request begin================================================");
        log.debug("URI         : {}", request.getURI());
        log.debug("Method      : {}", request.getMethod());
        log.debug("Headers     : {}", request.getHeaders() );
        log.debug("Request body: {}", new String(body, "UTF-8"));
        log.info("==========================request end================================================");
    }

    private ClientHttpResponse traceResponse(ClientHttpResponse response) throws IOException {
        if(!log.isDebugEnabled()){
            return response;
        }
        byte[] responseBytes=StreamUtils.copyToByteArray(response.getBody());
        log.info("============================response begin==========================================");
        log.debug("Status code  : {}", response.getStatusCode());
        log.debug("Status text  : {}", response.getStatusText());
        log.debug("Headers      : {}", response.getHeaders());
        if(log.isDebugEnabled()){
            log.debug("Response body: {}", new String(responseBytes, Charset.defaultCharset().name()));
        }
        log.info("=======================response end=================================================");
        // inputStream默认只能读取1次, 所以需要重新构造bodyInputStream返回
        return new BufferedClientHttpResponse(response, new ByteArrayInputStream(responseBytes));
    }


    private class BufferedClientHttpResponse implements ClientHttpResponse{

        private ClientHttpResponse innerResponse;
        private InputStream bodyInputStream;

        public BufferedClientHttpResponse(ClientHttpResponse innerResponse, InputStream bodyInputStream) {
            this.innerResponse = innerResponse;
            this.bodyInputStream=bodyInputStream;
        }

        @Override
        public HttpStatus getStatusCode() throws IOException {
            return innerResponse.getStatusCode();
        }

        @Override
        public int getRawStatusCode() throws IOException {
            return innerResponse.getRawStatusCode();
        }

        @Override
        public String getStatusText() throws IOException {
            return innerResponse.getStatusText();
        }

        @Override
        public void close() {
            innerResponse.close();
        }

        @Override
        public InputStream getBody() throws IOException {
            return bodyInputStream;
        }

        @Override
        public HttpHeaders getHeaders() {
            return innerResponse.getHeaders();
        }
    }



}
